// 实现这个项目的构建任务
const {
  src,
  dest,
  series,
  parallel,
  watch
} = require('gulp');

const del = require('del')
const browerSync = require('browser-sync')

// 导出的是一个方法
const loadPlugins = require('gulp-load-plugins')
// plugins是一个对象  所有插件都是对象的属性
const plugins = loadPlugins()

const clean = ()=>{
  return del(['dist','temp'])
}

const bs = browerSync.create()

const data = {
  menus:[
    {
      name:'Home',
      icon:'aperture',
      link:'index.html'
    },
    {
      name:'Features',
      link:'features.html'
    },
    {
      name:'About',
      link:'about.html'
    },
    {
      name:'Contact',
      link:'#',
      children:[
        {
          name:'Twitter',
          link:'https://teitter.com/w_zce'
        },
        {
          name:'About',
          link:'https://weibo.com/zceme'
        },
        {
          name:'divider'
        }
      ]
    },
  ],
  pkg: require('./package.json'),
  date: new Date()
}

const style = () => {
  // src指定一个选项参数
  return src('src/assets/styles/*.scss', { base:  'src' })
    // 函数的结果会返回一个结果流
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest('temp'))
    // 以流的方式推到浏览器
    .pipe(bs.reload({stream:true}))
}

const script = () => {
  return src('src/assets/scripts/*.js', { base:  'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('temp'))
    .pipe(bs.reload({stream:true}))
}

const page = ()=>{
  return src('src/*.html',{base:'src'})
    .pipe(plugins.swig({data}))
    .pipe(dest('temp'))
    .pipe(bs.reload({stream:true}))
}

const image = ()=>{
  return src('src/assets/images/**',{base:'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const font = ()=>{
  return src('src/assets/fonts/**',{base:'src'})
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const extra = ()=>{
  return src('public/**',{base:'public'})
    .pipe(dest('dist'))
}

const serve = () =>{
  // 两个参数 第一个参数是通配符 第二个参数是 执行的方法
  watch('src/assets/styles/*.scss',style)
  watch('src/assets/scripts/*.js',script)
  watch('src/*.html',page)
  // watch('src/assets/images/**',image)
  // watch('src/assets/fonts/**',font)
  // watch('public/**',extra)
  // 文件发生改变 调用bs模块提供的reload方法
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload)

  bs.init({
    notify: false,
    port:2080,
    open: true,
    // 启动之后监听的路径通配符，想要那些文件改变后刷新浏览器
    // files:'dist/**',
    // 指定根目录
    server:{
      // 先从第一个文件下面找 找不到再去找第二个
      baseDir: ['temp', 'src', 'public'],
      // 优先于baseDir
      routes:{
        '/node_modules':'node_modules'
      }
    }
  })
}

const useref = () => {
  return src('temp/*.html',{ base : 'temp' })
          .pipe(plugins.useref({searchPath:['temp', '.']}))
          // html js css
          // 自动创建转换流，根据if指定的条件是否要去执行具体的转换流
          .pipe(plugins.if(/\.js$/, plugins.uglify()))
          .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
          .pipe(plugins.if(/\.html$/, plugins.htmlmin({
            collapseWhitespace:true,
            minifyCSS:true,
            minifyJS:true
          })))
          .pipe(dest('dist'))
}

const compile = parallel(style, script, page)
// 先删除再去生成文件   上线之前执行的任务
const build = series(
    clean,
    parallel(
      series(compile, useref),
      image,
      font,
      extra
      )
    )

// 以最小的代价去启动服务
const develop = series(compile, serve)

module.exports = {
  clean,
  build,
  develop
}
